//
//  WJPDFListViewController.swift
//  PDFSign
//
//  Created by 李永彬 on 2025/9/22.
//

import UIKit

enum SignState {
    case signed
    case unSigned
}

class WJPDFListViewController: WJBaseViewViewController {
    
    var dataSources: [WJPDFListModel] = []
    
    var signState: SignState = .unSigned

    lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.register(WJPDFListCell.self, forCellReuseIdentifier: "WJPDFListCell")
        tableView.dataSource = self
        tableView.delegate = self
        tableView.separatorStyle = .none
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 72
        tableView.backgroundColor = .clear
        tableView.contentInset = UIEdgeInsets(top: 0,
                                              left: 0,
                                              bottom: 20,
                                              right: 0)
        tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNonzeroMagnitude))
        tableView.sectionHeaderHeight = CGFloat.leastNonzeroMagnitude
        tableView.contentInsetAdjustmentBehavior = .never
        tableView.showsVerticalScrollIndicator = false
        return tableView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        loadDatas()
        view.addSubview(tableView)
        tableView.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top)
            make.leading.trailing.bottom.equalToSuperview()
        }
    }
    
    func loadDatas() {
        do {
            switch signState {
            case .signed:
                self.title = "Signed"
                dataSources = try WJPDFListModel.findSignedFiles().sorted(by: { model1, model2 in
                    model1.createdDate > model2.createdDate
                })
            case .unSigned:
                self.title = "Unsigned"
                dataSources = try WJPDFListModel.findUnsignedFiles().sorted(by: { model1, model2 in
                    model1.createdDate > model2.createdDate
                })
            }
            
            if dataSources.isEmpty {
                wjUpdateState(.noData)
            } else {
                wjUpdateState(.finished)
            }
            self.tableView.reloadData()
        } catch {
            
        }
    }
    
    func goToPDFContentVC(_ listModel: WJPDFListModel) {
        let vc = WJPDFContentViewController()
        vc.listModel = listModel
        let nav = WJNavigationController(rootViewController: vc)
        nav.modalPresentationStyle = .fullScreen
        present(nav, animated: true)
    }
    
    func goToMoreActionVC(_ listModel: WJPDFListModel) {
        let vc = WJPDFOperationViewController()
        // 必须是.custom而不是.overFullScreen
        vc.modalPresentationStyle = .custom
        vc.transitioningDelegate = WJTransitionDelegate.shared
        vc.listModel = listModel
        vc.delegate = self
        present(vc, animated: true)
    }
}

extension WJPDFListViewController: UITableViewDataSource, UITableViewDelegate {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return self.dataSources.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "WJPDFListCell", for: indexPath) as! WJPDFListCell

        let listModel = self.dataSources[indexPath.section]
        cell.listModel = listModel
        cell.moreActionClosure = { [weak self] in
            guard let self = self else { return }
            self.goToMoreActionVC(listModel)
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        goToPDFContentVC(dataSources[indexPath.section])
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 72
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 12
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView()
        return view
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let view = UIView()
        return view
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0
    }
}

extension WJPDFListViewController: WJPDFOperationViewControllerDelegate {
    func operationPDF(_ controller: WJPDFOperationViewController, operationType: OperationType, listModel: WJPDFListModel) {
        var fileURL : URL? = nil
        
        if let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first,
           let path = listModel.filePath {
            fileURL = documentsURL.appendingPathComponent(path)
        }
        
        let fileName: String = (listModel.name ?? fileURL?.lastPathComponent) ?? ""
        
        guard let fileURL = fileURL else { return }
        
        switch operationType {
        case .rename:
            renamePDF(model: listModel)
        case .share:
            WJFileSharingManager.shared.shareFile(at: fileURL, withFileName: fileName, from: self)
        case .print:
            printPDF(from: fileURL, fileName: fileName)
        case .delete:
            deletePDF(model: listModel, fileURL: fileURL)
        }
    }
    
    func renamePDF(model: WJPDFListModel) {
        let alertController = UIAlertController(
            title: "Rename",
            message: nil,
            preferredStyle: .alert
        )

        alertController.addTextField { textField in
            textField.placeholder = nil
            textField.text = model.name
            textField.autocapitalizationType = .sentences
            textField.clearButtonMode = .whileEditing
        }

        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
        alertController.addAction(cancelAction)
        let okAction = UIAlertAction(title: "OK", style: .default) { [weak self] _ in
            guard let self = self else { return }
            // 获取文本框内容
            if let textField = alertController.textFields?.first,
               let inputText = textField.text, !inputText.isEmpty {
                if isValidFileName(inputText) {
                    model.name = inputText
                    let success = try? model.save()
                    if success == 1 {
                        for listMode in self.dataSources {
                            if listMode.id == model.id {
                                listMode.name = inputText
                            }
                        }
                    }
                    tableView.reloadData()
                }
            } else {
                print("用户没有输入内容")
            }
        }
        alertController.addAction(okAction)
        
        present(alertController, animated: true)
    }
    
    private func isValidFileName(_ fileName: String) -> Bool {
        // 定义非法字符集合
        let invalidCharacters = CharacterSet(charactersIn: "/\\?%*:|\"<>")
        
        // 检查是否包含非法字符
        let containsInvalidChars = fileName.rangeOfCharacter(from: invalidCharacters) != nil
        
        // 检查是否为空或只有空格
        let isEmpty = fileName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
        
        // 检查是否以点开头（隐藏文件）
        let isHiddenFile = fileName.hasPrefix(".")
        
        return !containsInvalidChars && !isEmpty && !isHiddenFile
    }
    
    func printPDF(from pdfURL: URL, fileName: String) {
        // 检查设备是否支持打印
        guard UIPrintInteractionController.isPrintingAvailable else {
            print("打印不可用")
            return
        }
        
        let printController = UIPrintInteractionController.shared
        
        // 配置打印信息
        let printInfo = UIPrintInfo.printInfo()
        printInfo.outputType = .general
        printInfo.jobName = fileName
        printController.printInfo = printInfo
        
        // 设置打印项，这里直接提供PDF文件的URL
        printController.printingItem = pdfURL
        
        // 呈现打印面板
        printController.present(animated: true) { (controller, completed, error) in
            if completed {
                print("打印或保存PDF成功")
            } else if let error = error {
                print("操作失败: \(error.localizedDescription)")
            }
        }
    }
    
    func deletePDF(model: WJPDFListModel, fileURL:URL) {
        let success = (try? model.delete()) ?? false
        if success {
            if FileManager.default.fileExists(atPath: fileURL.path) {
               try? FileManager.default.removeItem(atPath: fileURL.path)
            }
            dataSources.removeAll(where: { $0.id == model.id })
            if dataSources.isEmpty {
                wjUpdateState(.noData)
            } else {
                wjUpdateState(.finished)
            }
        }
        tableView.reloadData()
    }
}

extension WJPDFListViewController: WJNoDataProtocol {
    var wjStateContainer: UIView {
        return self.tableView
    }
    
    func wjFrame(for state: WJState) -> CGRect? {
        switch state {
        case .noData:
            return CGRect(x: 0, y: 248, width: view.bounds.width, height: 300)
        default:
            return nil
        }
    }
    
    func wjImage(for state: WJState) -> UIImage? {
        switch state {
        case .noData:
            return UIImage(named: "no_document_icon")
        default:
            return nil
        }
    }
    
    func wjButtonTitle(for state: WJState) -> String? {
        return nil
    }
    
    func wjTitle(for state: WJState) -> String {
        switch state {
        case .noData:
            return "No document here yet."
        default:
            return ""
        }
    }
    
    func wjMessage(for state: WJState) -> String {
        return ""
    }
    
    func wjDidTapStateButton() {
        
    }
}
